package whf.framework.tools.generator.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.CharArrayWriter;
import java.io.File;
import java.lang.reflect.Constructor;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import whf.framework.tools.generator.cfg.Config;
import whf.framework.util.StringUtils;

/**
 * <p>Title: 代码生成工具</p>
 *
 * <p>Description: </p>
 *
 * <p>Copyright: Copyright (c) 2006</p>
 *
 * <p>Company: whf</p>
 *
 * @author wanghaifeng
 * @version 1.0
 */
public class MainFrame extends JFrame {
	private static DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
    private Config config = new Config();

    private BorderLayout borderLayout1 = new BorderLayout();
    private DataPanel dataPanel = new DataPanel();
    private JPanel centerPanel = new JPanel();
    private JPanel buttonPanel = new JPanel();
    private BorderLayout borderLayout2 = new BorderLayout();
    private JButton jButton1 = new JButton();
    private JButton jButton2 = new JButton();
    private JLabel columnCountLabel = new JLabel();
    private JSpinner columnCountSpinner = new JSpinner();
    private JLabel filterLabel = new JLabel();
    private JTextField filterText = new JTextField();
    private TablesPanel tablesPanel = new TablesPanel();
    private JPanel bottomPanel = new JPanel();
    private JPanel jPanel3 = new JPanel();
    private BorderLayout borderLayout3 = new BorderLayout();
    private JLabel jLabel1 = new JLabel();
    private BorderLayout borderLayout4 = new BorderLayout();

    private JTextArea logTextArea = new JTextArea();
    private JScrollPane jScrollPane1 = new JScrollPane(logTextArea);
    private JSplitPane jSplitPane1 = new JSplitPane();
    
    private JMenuBar jMenuBar1 = new JMenuBar();
    private JMenu m_file = new JMenu();
    private JMenuItem mi_open = new JMenuItem();
    private JMenuItem mi_save = new JMenuItem();
    private JMenuItem mi_saveas = new JMenuItem();
    private JMenuItem mi_exit = new JMenuItem();
    private JMenu m_op = new JMenu();
    private JMenuItem mi_viewtables = new JMenuItem();
    private JMenuItem mi_code = new JMenuItem();
    private JMenuItem mi_cleanlog = new JMenuItem();
    private JMenu m_help = new JMenu();
    private JMenuItem mi_about = new JMenuItem();
    private JMenuItem mi_help = new JMenuItem();

    public MainFrame() {
        try {
            jbInit();
            this.setSize(800,600);
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

    private void jbInit() throws Exception {
        getContentPane().setLayout(borderLayout1);
        jButton1.setText("查看数据库表");
        jButton1.addActionListener(new MainFrame_jButton1_actionAdapter(this));
        jButton2.setText("生成代码");
        jButton2.addActionListener(new MainFrame_jButton2_actionAdapter(this));
        columnCountSpinner.setValue(new Integer(1));
        columnCountLabel.setText("   显示列数:");
        tablesPanel.setToolTipText("表");
        filterLabel.setText("   表名匹配");
        filterText.setPreferredSize(new Dimension(100,20));
        this.addWindowListener(new MainFrame_this_windowAdapter(this));
        bottomPanel.setLayout(borderLayout3);
        jLabel1.setForeground(Color.red);
        jLabel1.setText("操作日志:");
        jPanel3.setLayout(borderLayout4);
        bottomPanel.setBackground(new Color(201, 201, 201));
        bottomPanel.setPreferredSize(new Dimension(169, 100));

        jSplitPane1.setOrientation(JSplitPane.VERTICAL_SPLIT);
        jSplitPane1.setTopComponent(centerPanel);
        jSplitPane1.setBottomComponent(bottomPanel);

        //this.getContentPane().add(centerPanel, java.awt.BorderLayout.CENTER);
        centerPanel.setLayout(borderLayout2);
        //
        this.setJMenuBar(jMenuBar1);
        this.setTitle("WHF框架代码生成器");
        m_file.setText("文件");
        mi_open.setText("打开");
        mi_save.setText("保存");
        mi_saveas.setText("另存为");
        m_op.setText("操作");
        mi_viewtables.setText("查看数据表");
        mi_code.setText("生成代码");
        mi_cleanlog.setText("清除日志");
        m_help.setText("帮助");
        mi_about.setText("关于");
        mi_help.setText("帮助");
        mi_exit.setText("退出");
        buttonPanel.setPreferredSize(new Dimension(191, 35));
        centerPanel.add(buttonPanel, java.awt.BorderLayout.NORTH);
        buttonPanel.add(jButton1);
        buttonPanel.add(jButton2);
        buttonPanel.add(filterLabel);
        buttonPanel.add(filterText);
        buttonPanel.add(columnCountLabel);
        buttonPanel.add(columnCountSpinner);
        centerPanel.add(tablesPanel, java.awt.BorderLayout.CENTER);
        jPanel3.add(jLabel1, java.awt.BorderLayout.WEST);
        bottomPanel.add(jPanel3, java.awt.BorderLayout.NORTH);
        bottomPanel.add(jScrollPane1, java.awt.BorderLayout.CENTER);

        this.getContentPane().add(jSplitPane1, java.awt.BorderLayout.CENTER);

        //this.getContentPane().add(bottomPanel, java.awt.BorderLayout.NORTH);
        this.getContentPane().add(dataPanel, java.awt.BorderLayout.NORTH);
        jMenuBar1.add(m_file);
        jMenuBar1.add(m_op);
        jMenuBar1.add(m_help);
        m_file.add(mi_open);
        m_file.add(mi_save);
        m_file.add(mi_saveas);
        m_file.addSeparator();
        m_file.add(mi_exit);
        m_op.add(mi_viewtables);
        m_op.add(mi_code);
        m_op.addSeparator();
        m_op.add(mi_cleanlog);
        m_help.add(mi_help);
        m_help.add(mi_about);
        
        mi_open.addMouseListener(new MyMouseListener(){
        	public void mousePressed(MouseEvent e){
        		JFileChooser fileChooser = new JFileChooser();
        		fileChooser.setDialogTitle("请选择属性存储文件！");
        		fileChooser.setDialogType(JFileChooser.OPEN_DIALOG);
        		fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
        		if(!StringUtils.isEmpty(config.getFilename())){
        			File file = new File(config.getFilename());
        			if(file.exists()){
                		fileChooser.setCurrentDirectory(file);
        			}
        		}
				int result=fileChooser.showOpenDialog(null);  
				if(result==JFileChooser.APPROVE_OPTION){   
					File f = fileChooser.getSelectedFile();
					config.setFilename(f.getAbsolutePath());
					try{
						config.loadFromPropertiesFile();
						dataPanel.loadFromConfig(config);
			            int columnCount = ((Integer)columnCountSpinner.getValue()).intValue();
			            if(columnCount < 1) columnCount = 1;
						tablesPanel.showTables(config, columnCount, filterText.getText(), true);
					}catch(Exception ex){
						log(ex);
					}
				}
        	}
        });
        
        mi_save.addMouseListener(new MyMouseListener(){
        	public void mousePressed(MouseEvent e){
        		config = dataPanel.getConfig(config);
        		config.setTables(tablesPanel.getSelectedTables());
        		File file = new File(config.getFilename() == null?"": config.getFilename());
        		if(!file.exists()){
            		log("文件不存在，请使用另存为保存！");
            		JFileChooser fileChooser = new JFileChooser();
            		fileChooser.setDialogTitle("请选择属性存储文件！");
            		fileChooser.setDialogType(JFileChooser.SAVE_DIALOG);
        			if(file.exists()){
                		fileChooser.setCurrentDirectory(file);
        			}
    				int result=fileChooser.showSaveDialog(null);
    				if(result==JFileChooser.APPROVE_OPTION){   
    					File f = fileChooser.getSelectedFile();
    					config.setFilename(f.getAbsolutePath());
    					try{
    						config.saveToPropertiesFile();
    					}catch(Exception ex){
    						log(ex);
    					}
    				}
        		} 
        	}
        });
        
        mi_saveas.addMouseListener(new MyMouseListener(){
        	public void mousePressed(MouseEvent e){
        		config = dataPanel.getConfig(config);
        		config.setTables(tablesPanel.getSelectedTables());
        		JFileChooser fileChooser = new JFileChooser();
        		fileChooser.setDialogTitle("请选择属性存储文件！");
        		fileChooser.setDialogType(JFileChooser.SAVE_DIALOG);
        		if(!StringUtils.isEmpty(config.getFilename())){
        			File file = new File(config.getFilename());
        			if(file.exists()){
                		fileChooser.setCurrentDirectory(file);
        			}
        		}
				int result=fileChooser.showSaveDialog(null);
				if(result==JFileChooser.APPROVE_OPTION){   
					File f = fileChooser.getSelectedFile();
					config.setFilename(f.getAbsolutePath());
					try{
						config.saveToPropertiesFile();
					}catch(Exception ex){
						log(ex);
					}
				}
        	}
        });
        
        mi_exit.addMouseListener(new MyMouseListener(){
            public void mousePressed(MouseEvent e){
            	System.exit(1);
            }
        });
        
        mi_viewtables.addMouseListener(new MyMouseListener(){
        	public void mousePressed(MouseEvent e){
        		jButton1_actionPerformed(null);
        	}
        });
        
        mi_code.addMouseListener(new MyMouseListener(){
        	public void mousePressed(MouseEvent e){
        		jButton2_actionPerformed(null);
        	}
        });
        
        mi_about.addMouseListener(new MyMouseListener(){
        	public void mousePressed(MouseEvent e){
        		log("/*－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－*/");
        		log("/* 本程序由王海峰创建 2006-10-10");
        		log("/* 本程序一切所有权规王海峰所有,请珍惜他人劳动成果! ");
        		log("/* 你可以这样联系我:hotwhf@hotmail.com, g.wang.haifeng@gmail.com ");
        		log("/*－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－*/");
        	}
        });
        
        mi_cleanlog.addMouseListener(new MyMouseListener(){
        	public void mousePressed(MouseEvent e){
        		logTextArea.setText("");
        	}
        });
    }

    private void log(Object obj){
        if(obj == null) return;
        String str = obj.toString();
        if(obj instanceof Exception){
            Exception e = (Exception)obj;
            CharArrayWriter writer = new CharArrayWriter();
            e.printStackTrace(new java.io.PrintWriter(writer));
            str = writer.toString();
            e.printStackTrace();
        }
        String text = logTextArea.getText();
        if(text == null || "".equals(text)){
            text = str;
        } else {
            text += "\n\n" + sdf.format(new java.util.Date()) + ":\n"+str;
        }
        logTextArea.setText(text);
    }

    public static void main(String[] args) {
        MainFrame mainframe = new MainFrame();
        mainframe.setVisible(true);
    }

    public void this_windowClosing(WindowEvent e) {
        System.exit(0);
    }

    public void jButton1_actionPerformed(ActionEvent e) {
        try{
            dataPanel.checkValidation();
            log("配置数据正确!");
        }catch(Exception ex){
            log(ex.getMessage());
        }
        config = dataPanel.getConfig(this.config);
        (new Thread(new ViewTablesThread())).start();
    }

    public void jButton2_actionPerformed(ActionEvent e) {
        try{
            dataPanel.checkValidation();
            log("配置数据正确!");
        }catch(Exception ex){
            log(ex.getMessage());
            return;
        }
        config = dataPanel.getConfig(this.config);
        String selectedTables = tablesPanel.getSelectedTables();
        if("".equals(selectedTables)){
            log("没有选择表!");
            return;
        }
        log("选择的表:"+selectedTables);
        config.setTables(selectedTables);
        (new Thread(new CodingThread())).start();
    }

    class CodingThread implements Runnable{
        public void run(){
            log(config);
            log("开始生成代码,详细清查看控制台输出信息! ......");
            jButton2.setEnabled(false);
            mi_code.setEnabled(false);
            try {
                Class cls = Class.forName("whf.framework.tools.generator.db.DBCodeGenerator");
                Constructor cons = cls.getConstructor(new Class[]{Config.class});
                Object obj = cons.newInstance(new Object[]{config});
                cls.getMethod("generate", new Class[]{}).invoke(obj, new Object[]{});
            } catch (Exception ex) {
                log(ex);
            } finally{
                jButton2.setEnabled(true);
                mi_code.setEnabled(true);
            }
            log("生成代码完成!");
        }
    }
    
    class ViewTablesThread implements Runnable{
    	public void run(){
            int columnCount = ((Integer)columnCountSpinner.getValue()).intValue();
            if(columnCount < 1) columnCount = 1;
            jButton1.setEnabled(false);
            jButton2.setEnabled(false);
            mi_code.setEnabled(false);
            mi_viewtables.setEnabled(false);
            log("正在打开数据库查看表!......");
            log(config);
            try{
                tablesPanel.showTables(config, columnCount, filterText.getText(), false);
                log("成功打开数据库!");
            }catch(Exception ex){
                log(ex);
                log("打开数据库失败!");
            } finally{
            	jButton1.setEnabled(true);
                jButton2.setEnabled(true);
                mi_code.setEnabled(true);
                mi_viewtables.setEnabled(true);
            }
    	}
    }
    
    class MyMouseListener implements MouseListener{

		/* (non-Javadoc)
		 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
		 */
		public void mouseClicked(MouseEvent e) {
		}

		/* (non-Javadoc)
		 * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
		 */
		public void mouseEntered(MouseEvent e) {
		}

		/* (non-Javadoc)
		 * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
		 */
		public void mouseExited(MouseEvent e) {
		}

		/* (non-Javadoc)
		 * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
		 */
		public void mousePressed(MouseEvent e) {
		}

		/* (non-Javadoc)
		 * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
		 */
		public void mouseReleased(MouseEvent e) {
		}
    	
    }
}


class MainFrame_jButton2_actionAdapter implements ActionListener {
    private MainFrame adaptee;
    MainFrame_jButton2_actionAdapter(MainFrame adaptee) {
        this.adaptee = adaptee;
    }

    public void actionPerformed(ActionEvent e) {
        adaptee.jButton2_actionPerformed(e);
    }
}


class MainFrame_jButton1_actionAdapter implements ActionListener {
    private MainFrame adaptee;
    MainFrame_jButton1_actionAdapter(MainFrame adaptee) {
        this.adaptee = adaptee;
    }

    public void actionPerformed(ActionEvent e) {
        adaptee.jButton1_actionPerformed(e);
    }
}


class MainFrame_this_windowAdapter extends WindowAdapter {
    private MainFrame adaptee;
    MainFrame_this_windowAdapter(MainFrame adaptee) {
        this.adaptee = adaptee;
    }

    public void windowClosing(WindowEvent e) {
        adaptee.this_windowClosing(e);
    }
}
